package com.sky.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.OrdersCancelDTO;
import com.sky.dto.OrdersConfirmDTO;
import com.sky.dto.OrdersPageQueryDTO;
import com.sky.dto.OrdersRejectionDTO;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.exception.OrderBusinessException;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.AdminOrderMapper;
import com.sky.mapper.UserOrderMapper;
import com.sky.service.AdminOrderService;
import com.sky.vo.OrderDetailVO;
import com.sky.vo.OrderSearchPageVO;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderVO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;


@Service
@RequiredArgsConstructor
public class AdminOrderServiceImpl implements AdminOrderService {

    private final AdminOrderMapper adminOrderMapper;

    private final OrderDetailMapper orderDetailMapper;

    private final UserOrderMapper userOrderMapper;


    @Override
    public OrderSearchPageVO conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO) {
        PageHelper.startPage(ordersPageQueryDTO.getPage(),ordersPageQueryDTO.getPageSize());
        ordersPageQueryDTO.setUserId(BaseContext.getCurrentId());
        OrderSearchPageVO orderSearchPageVO = new OrderSearchPageVO();
        List<Orders> ordersList = adminOrderMapper.selectOrdersPage(ordersPageQueryDTO);
        PageInfo<Orders> pageInfo = PageInfo.of(ordersList);
        List<Orders> orders = pageInfo.getList();
        List<OrderVO> orderVOList = orders.stream().map(orders1 -> {
            OrderVO orderVO = new OrderVO();
            BeanUtils.copyProperties(orders1,orderVO);
            orderVO.setOrderDishes(getDishString(orders1));
            return orderVO;
        }).collect(Collectors.toList());
        orderSearchPageVO.setTotal(pageInfo.getTotal());
        orderSearchPageVO.setRecords(orderVOList);
        return orderSearchPageVO;
    }

    @Override
    public OrderStatisticsVO selectStatisticsCount() {

        //待接单数量
        Integer toBeConfirmed = adminOrderMapper.selectByStatus(Orders.TO_BE_CONFIRMED);
        //待派送数量
        Integer confirmed = adminOrderMapper.selectByStatus(Orders.CONFIRMED);
        //派送中数量
        Integer deliveryInProgress = adminOrderMapper.selectByStatus(Orders.DELIVERY_IN_PROGRESS);

        OrderStatisticsVO orderStatisticsVO = new OrderStatisticsVO();
        orderStatisticsVO.setToBeConfirmed(toBeConfirmed);
        orderStatisticsVO.setConfirmed(confirmed);
        orderStatisticsVO.setDeliveryInProgress(deliveryInProgress);
        return orderStatisticsVO;
    }

    @Override
    public OrderDetailVO selectDetailsById(Long id) {
        OrderDetailVO orderDetailVO = new OrderDetailVO();
        Orders orders = adminOrderMapper.selectById(id);
        String orderDishes = getDishString(orders);
        List<OrderDetail> orderDetailList = orderDetailMapper.selectByOrderId(id);
        BeanUtils.copyProperties(orders,orderDetailVO);
        orderDetailVO.setOrderDishes(orderDishes);
        orderDetailVO.setOrderDetailList(orderDetailList);
        return orderDetailVO;
    }

    //接单
    @Override
    public void confirm(OrdersConfirmDTO ordersConfirmDTO) {
        Orders orders = new Orders();
        orders.setId(ordersConfirmDTO.getId());
        orders.setStatus(Orders.CONFIRMED);
        userOrderMapper.updateOrders(orders);
    }

    @Override
    public void rejection(OrdersRejectionDTO ordersRejectionDTO) {
        Orders orders = userOrderMapper.selectOrdersById(ordersRejectionDTO.getId());

        //待接单状态才能拒单
        if (orders.getStatus() != 2){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        //todo 退款操作

        orders.setStatus(Orders.CANCELLED);
        orders.setPayStatus(Orders.REFUND);
        orders.setRejectionReason(ordersRejectionDTO.getRejectionReason());
        orders.setCancelTime(LocalDateTime.now());

        userOrderMapper.updateOrders(orders);

    }

    @Override
    public void cancel(OrdersCancelDTO ordersCancelDTO) {
        Orders orders = userOrderMapper.selectOrdersById(ordersCancelDTO.getId());

        if (orders.getStatus() != 1 && orders.getStatus() != 2 && orders.getStatus() != 3){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        //todo 退款操作

        orders.setStatus(Orders.CANCELLED);
        orders.setPayStatus(Orders.REFUND);
        orders.setCancelReason(ordersCancelDTO.getCancelReason());
        orders.setCancelTime(LocalDateTime.now());

        //根据订单id修改订单
        userOrderMapper.updateOrders(orders);
    }

    @Override
    public void delivery(Long id) {
        Orders orders = userOrderMapper.selectOrdersById(id);
        if (orders.getStatus() != 3){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        //更改订单状态
        orders.setStatus(Orders.DELIVERY_IN_PROGRESS);
        userOrderMapper.updateOrders(orders);
    }

    @Override
    public void complete(Long id) {
        Orders orders = userOrderMapper.selectOrdersById(id);

        if (orders.getStatus() != 4){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        //更改订单状态
        orders.setStatus(Orders.COMPLETED);
        orders.setDeliveryTime(LocalDateTime.now());
        userOrderMapper.updateOrders(orders);
    }

    private String getDishString(Orders orders) {
        List<OrderDetail> orderDetailList = orderDetailMapper.selectByOrderId(orders.getId());
        List<String> orderDishList = orderDetailList.stream().map(orderDetail -> {
            String orderDish = orderDetail.getName() + "*" + orderDetail.getNumber();
            return orderDish;
        }).collect(Collectors.toList());
        String orderDishes = StringUtils.join(orderDishList, ",");
        return orderDishes;
    }
}
